
#include <linux/module.h>
#include <linux/kernel.h>     		/* printk()?????? */
#include <linux/fs.h> 				/* struct file_operations, register_chrdev(), ... */
#include <linux/sched.h>			/* ??????? */
#include <linux/types.h> 			/* u8, u16, u32 ... */
#include <linux/version.h>
#include <linux/init.h>       //module_init() and module_exit() ??????? 
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/irq.h>  
#include <linux/delay.h>

#include <asm/arch/gpio.h>
//#include "IOdrv.h"
 static struct input_dev *button_dev; 
void bibi(unsigned int v)
{
	   at91_set_gpio_value(AT91_PIN_PA8,1);
	   mdelay(v);
	   at91_set_gpio_value(AT91_PIN_PA8,0);
	   mdelay(v);
}

static irqreturn_t button_interrupt(int irq, void*dummy, struct pt_regs *fp)  
 {  
 		int res;
		bibi(100);
		res = at91_get_gpio_value(AT91_PIN_PB16);
        input_report_key(button_dev, BTN_1,res); 
		printk("<2>" "上报的键值:%d\n",res);
        input_sync(button_dev); 
		return IRQ_HANDLED ; 
 }   

 static int __init button_init(void)  
 {  
        int error;  
		bibi(1000);
		at91_set_gpio_input(AT91_PIN_PB16,1);
		at91_set_deglitch(AT91_PIN_PB16,1);
		set_irq_type(AT91_PIN_PB16,IRQF_TRIGGER_RISING);
        
        bibi(1000); 
        button_dev = input_allocate_device();  
		bibi(1000);
        if (!button_dev) {  
                 printk(KERN_ERR"button.c: Not enough memory\n");  
                 error = -ENOMEM;  
                 return error;  
        }  
  		bibi(1000);
        button_dev->evbit[0] = BIT(EV_KEY);  
        button_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);  
  
        error = input_register_device(button_dev);  
        if (error) {  
                 printk(KERN_ERR"button.c: Failed to register device\n");  
                 input_free_device(button_dev); 
				 return error ;
        }  
  		if (request_irq(AT91_PIN_PB16, button_interrupt,0,"but_irq",NULL))
		{  
                 printk(KERN_ERR "button.c: Can't allocate irq \n");  
                 return -EBUSY;  
        }  //申请中断，上升沿触发 
        return 0;  
   
 }  
  
 static void __exit button_exit(void)  
 {  
	   printk("<0>""button_exit\n");
       input_unregister_device(button_dev);  
       free_irq(AT91_PIN_PB16, button_interrupt); 

}  
  
MODULE_LICENSE("GPL");
module_init(button_init);  
module_exit(button_exit);  
